package com.ruoyi.quartz.task;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.quartz.domain.TbConfig;
import com.ruoyi.quartz.domain.TbConfigEnum;
import com.ruoyi.quartz.domain.TbListData;
import com.ruoyi.quartz.service.ITbConfigService;
import com.ruoyi.quartz.service.ITbListDataService;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 定时任务调度测试
 * 
 * @author ruoyi
 */
@Slf4j
@Component("ryTask")
public class RyTask
{
    @Autowired
    private ITbListDataService tbService;

    @Autowired
    private ITbConfigService tbConfigService;

    private boolean pass = true;

    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
    {
        System.out.println(StringUtils.format("执行多参方法： 字符串类型{}，布尔类型{}，长整型{}，浮点型{}，整形{}", s, b, l, d, i));
    }

    public void ryParams(String params)
    {
        System.out.println("执行有参方法：" + params);
    }

    public void ryNoParams()
    {
        System.out.println("执行无参方法");
    }

    private <T> T getConfig(Class<T> beanClass) {
        TbConfig config = tbConfigService.selectTbConfigByConfigType(TbConfigEnum.TB.getType());
        if(config != null){
            if(!config.getUrl().endsWith("/")){
                config.setUrl(config.getUrl()+"/");
            }
            config.setSpm("?"+config.getSpm()+"&");
            return (T)config;
        }
        return null;
    }
    /**
     * 获取淘宝房源第一页数据
     * @throws InterruptedException
     */
    public void collectTaoBao(Integer startPageNo) throws InterruptedException {
        pass = true;
        TbConfig config = getConfig(TbConfig.class);
        if(config == null){
            log.info("获取spm配置信息失败,查询为空");
            return;
        }
        startPageNo = startPageNo<2?2:startPageNo;
        String url = config.getUrl();
        String spm = config.getSpm();
        String cookie = config.getCookie();
        //设置全局cookie
        String res = HttpUtil.get(url);
        Document document = Jsoup.parseBodyFragment(res);
        Element body = document.body();
        Elements aEle = body.select("a:contains(住宅用房)");
        String firstPage = aEle.attr("href");
        log.info("采集住宅用房第一页数据:"+ firstPage);
        if(StringUtils.isNotBlank(firstPage)){
            res = HttpUtil.get(firstPage);
            document = Jsoup.parseBodyFragment(res);
            // 页码处理
            String allPageNo = document.getElementsByClass("page-total").text();
            int pageNo = 0;
            if(StringUtils.isNotBlank(allPageNo)){
                pageNo = Integer.parseInt(allPageNo);
            }
            String baseUrl = document.getElementsByClass("J_PageSkipSubmit").attr("data-url");
            // 解析数据
            try{
                handlerSaveDb(document);
            }catch (Exception e){
                log.error("爬取{} 页码1 出现异常：{}", firstPage, e.getMessage());
            }
            //翻页
            for (int i = startPageNo; i <= pageNo; i++) {
                //间隔翻页
                long second = RandomUtil.randomLong(2 * 1000, 4 * 1000);
                Thread.sleep(second);
                log.info("采集住宅用房第{}页数据", i);
                if(pass){
                    url = handlerEveryPageData(i, baseUrl, url, spm, cookie);
                }else{
                    log.info("采集结束！！！！");
                    return;
                }
            }
            log.info("采集结束！！！！");
        }
    }

    /**
     * 获取第二页之后的数据
     * @param pageNo
     * @param baseUrl
     */
    private String handlerEveryPageData(int pageNo, String baseUrl, String referer,String spm, String cookie){
        if(baseUrl == null) return null;
        // 处理页码路径
        if(!baseUrl.startsWith("https")){
            baseUrl = "https:"+ baseUrl.trim() + pageNo;
        }else{
            baseUrl = baseUrl.trim() + pageNo;
        }
        Map<String, String> header = new HashMap<>(3);
        header.put("referer", referer);
        log.info("referer==>>:{}", referer);
        header.put("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0");
        header.put("sec-ch-ua-platform", "Windows");

        if(pageNo >= 2){
            //处理spm-> {}
            baseUrl = baseUrl.replaceAll("\\?", StringUtils.format(spm, pageNo));
            header.put("Cookie", cookie);
        }
        HttpRequest request = HttpUtil.createGet(baseUrl);
        request.addHeaders(header);
        HttpResponse response = request.execute();
        String res = response.body();
        if(StringUtils.isEmpty((res))){
            log.info("获取到数据为空字符，地址为：{}", baseUrl);
            if(pass){
                pass = false;
            }
            return null;
        }
        Document document = Jsoup.parseBodyFragment(res);
        try{
            handlerSaveDb(document);
        }catch (Exception e){
            log.error("爬取{} 页码{} 出现异常：{}", baseUrl, pageNo, e.getMessage());
            pass = false;
        }
        return baseUrl;
    }

    /**
     * 执行批量入库
     * @param document
     */
    private void handlerSaveDb(Document document){
        String data = document.getElementById("sf-item-list-data").data();
        JSONObject jsonObject = JSONUtil.parseObj(data, true);
        List<TbListData> dataList = JSONUtil.toList(jsonObject.getStr("data"), TbListData.class);
        if(!dataList.isEmpty()){
            tbService.batchInsert(dataList);
        }
    }

}
